package com.example.zqq.wuzichess;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import java.util.ArrayList;

/**
 * 棋盘 on 2017/11/3.
 */

public class ChessPanelView extends View {

    private int mViewWidth;                     //棋盘宽高
    private float gridHeight;                   //每格高度
    private float ratioPieceOfLineHeight = 3 * 1.0f / 4;        // 四分之三大小
    private boolean mIsWhite = true;            //判断落下的棋子是否是白色
    private boolean mIsGameOver;                //判断游戏结束
    private boolean mIsWhiteWin;                //判断是否白棋 胜利

    private ArrayList<Point> mWhiteArray;       //记录棋子位置列表
    private ArrayList<Point> mBlackArray;

    private Paint paint;
    private Bitmap mWhiteChess, mBlackChess;    //黑白棋

    public ChessPanelView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    /**
     * 1. 初始化（初始执行）
     */
    private void init() {
//        Log.e("Tag--1", "init");
        paint = new Paint();
        mWhiteArray = new ArrayList<>();
        mBlackArray = new ArrayList<>();

        paint.setColor(Color.WHITE);       //0x88000000
        paint.setAntiAlias(true);
        paint.setDither(true);
        paint.setStyle(Paint.Style.STROKE);//设置空心实心

        mWhiteChess = BitmapFactory.decodeResource(getResources(), R.mipmap.stone_w2);
        mBlackChess = BitmapFactory.decodeResource(getResources(), R.mipmap.stone_b1);
    }


    /**
     * 2. 测量View的大小，使View的长宽一致。（初始执行）
     *
     * 该方法指定该控件在屏幕上的大小
     * 两个参数是由上一层控件传入的大小----->
     * 参数：不是一般的尺寸数值，而是将模式和尺寸组合在一起的数值
     * 然后调用setMeasuredDimension(int, int)设置实际大小。
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        Log.e("Tag--2", "onMeasure");

        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int widthModel = MeasureSpec.getMode(widthMeasureSpec);

        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int heightModel = MeasureSpec.getMode(heightMeasureSpec);

        int width = Math.min(heightSize, widthSize);

//        Log.e("Tag--2-widthSize:", String.valueOf(widthSize));//720
//        Log.e("Tag--2-heightSize", String.valueOf(heightSize));//1158

        //EXACTLY是精确尺寸
        //AT_MOST是最大尺寸
        //UNSPECIFIED是未指定尺寸
        if (widthModel == MeasureSpec.UNSPECIFIED) {
            width = heightSize;
        } else if (heightModel == MeasureSpec.UNSPECIFIED) {
            width = widthSize;
        }
//        Log.e("Tag--2-width", String.valueOf(width));//720

        setMeasuredDimension(width, width);
    }

    /**
     * 3 onSizeChanged方法在布局的阶段，如果View的大小发生改变，此方法得到调用。
     * （初始执行）
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
//        Log.e("Tag--3", "onSizeChanged");

        mViewWidth = w;                                         //棋盘高宽
        gridHeight = mViewWidth * 1.0f / Constants.MAX_LINE;        //每个格子高度

        int chessWidth = (int) (gridHeight * ratioPieceOfLineHeight);   //棋子的 大小 是 格子的3/4
//        int chessWidth = (int) (gridHeight * 1);   //若棋子的 大小 是 格子的1倍，则棋子需要从【0,0】开始画图

        mWhiteChess = Bitmap.createScaledBitmap(mWhiteChess, chessWidth, chessWidth, false); //缩放位图
        mBlackChess = Bitmap.createScaledBitmap(mBlackChess, chessWidth, chessWidth, false);

//        Log.e("Tag--3-mViewWidth", String.valueOf(mViewWidth));//取最小的宽度720
//        Log.e("Tag--3-h", String.valueOf(h));//720
//        Log.e("Tag--3-oldw", String.valueOf(oldw));//0
//        Log.e("Tag--3-oldh", String.valueOf(oldh));//0
        Log.e("Tag--3-gridHeight格子", String.valueOf(gridHeight));//720/15=48
        Log.e("Tag--3-chessWidth棋子", String.valueOf(chessWidth));//48*3/4=36
    }


    /**
     * 4. 处理我们下棋子的位置：（触摸执行）
     * 为什么执行两遍？？？？
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.e("Tag--4", "onTouchEvent");
        if (mIsGameOver) {
            return false;
        }
        int action = event.getAction();
        if (action == MotionEvent.ACTION_UP) {
            int x = (int) event.getX();
            int y = (int) event.getY();

//            Log.e("Tag--4-event.x", String.valueOf(x));//点击的位置
//            Log.e("Tag--4-event.y", String.valueOf(y));//对比绘制棋子的左上角

            Point point = getValidPoint(x, y);          //所以point.x为1、2--到14
                                                        //point包含的点 为 15*15 数组
            if (mWhiteArray.contains(point) || mBlackArray.contains(point)) {
                return false;
            }
            /**
             *  point包含的点 为 15*15 数组
             */
            //判断落下的棋子是否是白色
            if (mIsWhite) {
//                Log.e("Tag--4-Wpoint", point.toString());
                mWhiteArray.add(point);
            } else {
//                Log.e("Tag--4-Bpoint", point.toString());
                mBlackArray.add(point);
            }

            //更新棋盘
            invalidate();       //使视图无效
            mIsWhite = !mIsWhite;
        }
        return true;
    }

    //获取点击的点--//point包含的点 为 15*15 数组
    private Point getValidPoint(int x, int y) {
        int validX = (int) (x / gridHeight);    //小于48的触摸点均为0,48-72均为1
        int validY = (int) (y / gridHeight);
        return new Point(validX, validY);
    }

    /**
     * 5. 棋盘的绘制工作 （触摸执行）
     * 如果继承自View（初始执行）
     * 如果继承自SurfaceView（需要自己定制）
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.e("Tag--5", "onDraw");
        drawBoard(canvas);           // 绘制棋盘的网格
        drawPieces(canvas);          // 绘制棋盘的黑白棋子
        checkGameOver();             // 检查游戏是否结束
    }

    // 6. 绘制棋盘的网格
    private void drawBoard(Canvas canvas) {
        int w = mViewWidth;             //棋盘高宽 720
        float lineHeight = gridHeight;  //格子高宽 48 =720/15  chessHeight = 43*3/4=36

//        Log.e("Tag--6-lineHeight", String.valueOf(lineHeight));

        //此处画图 留有空隙（四边）
        for (int i = 0; i < Constants.MAX_LINE; i++) {  //画了15条线
            int startx = (int) (lineHeight / 2);    //24
            int endx = (int) (w - lineHeight / 2);  //696
            int y = (int) ((0.5 + i) * lineHeight); //（即左上角【24,24】开始画图）

//            Log.e("Tag--6-y", String.valueOf(y));//24-72-120-168-....648-696

            canvas.drawLine(startx, y, endx, y, paint);
            canvas.drawLine(y, startx, y, endx, paint);
        }
    }

    //7. 绘制棋盘的黑白棋子
    private void drawPieces(Canvas canvas) {
        //画白棋
        for (int i = 0, n = mWhiteArray.size(); i < n; i++) {
            Point whitePoint = mWhiteArray.get(i);
//            Log.e("Tag--7-W-Point", whitePoint.toString());

            float left = (whitePoint.x + (1 - ratioPieceOfLineHeight) / 2) * gridHeight;//?*格子的宽度=棋子的间距
            float top = (whitePoint.y + (1 - ratioPieceOfLineHeight) / 2) * gridHeight;

            //当棋子的宽度==格子的宽度时   间距从零开始  //?*格子的宽度=棋子的间距
//            float left = (whitePoint.x + 0) * gridHeight;
//            float top = (whitePoint.y + 0) * gridHeight;

//            Log.e("Tag--7-W-left", String.valueOf(left));
//            Log.e("Tag--7-W-top", String.valueOf(top));
            canvas.drawBitmap(mWhiteChess, left, top, null);//(从左顶部开始画棋子)棋子的 大小 是 格子的3/4
        }

        //画黑棋
        for (int i = 0, n = mBlackArray.size(); i < n; i++) {
            Point blackPoint = mBlackArray.get(i);
            float left = (blackPoint.x + (1 - ratioPieceOfLineHeight) / 2) * gridHeight;
            float top = (blackPoint.y + (1 - ratioPieceOfLineHeight) / 2) * gridHeight;

            //当棋子的宽度==格子的宽度时   间距从零开始  //?*格子的宽度=棋子的间距
//            float left = (blackPoint.x + 0) * gridHeight;
//            float top = (blackPoint.y + 0) * gridHeight;

//            Log.e("Tag--7-B-Point", blackPoint.toString());
//            Log.e("Tag--7-B-left", String.valueOf(left));
//            Log.e("Tag--7-B-top", String.valueOf(top));
            canvas.drawBitmap(mBlackChess, left, top, null);
        }
    }

    // 8. 检查游戏是否结束
    private void checkGameOver() {
        CheckWinner checkWinner = new CheckWinner();
        boolean whiteWin = checkWinner.checkFiveWinner(mWhiteArray);    //判断白棋 的 点 数组
        boolean blackWin = checkWinner.checkFiveWinner(mBlackArray);    //判断黑棋 的 点 数组

        if (whiteWin || blackWin) {
            mIsGameOver = true;         //onTauchEvent--->return false;
            mIsWhiteWin = whiteWin;

            String text = mIsWhiteWin ? "白棋胜利" : "黑棋胜利";
            Toast.makeText(getContext(), text, Toast.LENGTH_SHORT).show();
            ChessPanelView.setView.setview(text);
        }
    }



    // 再来一局
    public void start() {
        mWhiteArray.clear();
        mBlackArray.clear();
        mIsGameOver = false;
        mIsWhiteWin = false;
        invalidate();           //使视图无效-- //更新棋盘
    }

    private static setView setView;

    public void setSetView(ChessPanelView.setView setView) {
        ChessPanelView.setView = setView;
    }

    interface setView{
        void setview(String s);
    }

    /******-----保存残局，例如切换横坚屏时 ------------************/
    private static final String INSTANCE = "instance";
    private static final String INSTANCE_GAME_OVER = "instance_game_over";
    private static final String INSTANCE_WHITE_ARRAY = "instance_white_array";
    private static final String INSTANCE_BLACK_ARRAY = "instance_black_array";

    @Override
    protected Parcelable onSaveInstanceState() {
        Bundle bundle = new Bundle();
        bundle.putParcelable(INSTANCE, super.onSaveInstanceState());
        bundle.putBoolean(INSTANCE_GAME_OVER, mIsGameOver);

        bundle.putParcelableArrayList(INSTANCE_BLACK_ARRAY, mBlackArray);
        bundle.putParcelableArrayList(INSTANCE_WHITE_ARRAY, mWhiteArray);

        return bundle;
    }

    //从bundle中恢复棋局
    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (state instanceof Bundle) {
            Bundle bundle = (Bundle) state;
            mIsGameOver = bundle.getBoolean(INSTANCE_GAME_OVER);
            mWhiteArray = bundle.getParcelableArrayList(INSTANCE_WHITE_ARRAY);
            mBlackArray = bundle.getParcelableArrayList(INSTANCE_BLACK_ARRAY);

            super.onRestoreInstanceState(bundle.getParcelable(INSTANCE));
            return;
        }
        super.onRestoreInstanceState(state);
    }
}
